#include "Vision.h"

#include "../ConsoleColor.h"
#include "../CommandManager.h"
#include "../GameObjects/Room.h"
#include "../GameObjects/Character.h"
#include "../GameObjects/Item.h"
#include "../Player.h"

#include <iostream>

void Vision::Init()
{
	CommandManager::getSingleton()->add(std::make_shared<Look>());
	CommandManager::getSingleton()->add(std::make_shared<Examine>());
}

///////////////////////////////////////
// LOOK
///////////////////////////////////////
Look::Look() : Command("look")
{
	add("l");
}
void Look::execute(const CharacterPtr &character, const RoomPtr &room, const std::vector<std::string> &args)
{
	//This is only for players
	if(character->hasPlayer() == false)
		return;

	if(args.empty())
	{
		room->look();
		return;
	}

	else if(args.size() == 1)
	{
        for(unsigned int i = 0; i < room->getExits().size(); i++)
		{
			//If argument is an object name, then look at the object.
			if(room->getExits()[i]->is(args[0]) || room->getExits()[i]->getNameAlias() == args[0])
			{
				room->getExits()[i]->look();
				return;
			}
		}
		for(unsigned int i = 0; i < room->getCharacters().size(); i++)
		{
			//If argument is a character name, then look at the character.
			if(room->getCharacters()[i]->is(args[0]))
			{
				room->getCharacters()[i]->look();
				return;
			}
		}
		for(unsigned int i = 0; i < room->getObjects().size(); i++)
		{
			//If argument is an object name, then look at the object.
			if(room->getObjects()[i]->is(args[0]))
			{
				room->getObjects()[i]->look();
				return;
			}
		}
        for(unsigned int i = 0; i < character->getItems().size(); i++)
		{
			//If argument is an object name, then look at the object.
			if(character->getItems()[i]->is(args[0]))
			{
				character->getItems()[i]->look();
				return;
			}
		}
	}
	else if(args.size() == 2)
	{
		if(args[0] == "in" || args[0] == "at")
		{
			if(args[1] == "hand" || args[1] == "hands")
			{
				if(character->hasPlayer())
				{
					const ItemPtr &item = character->getHeldItem();
					if(item)
						std::cout << "You're holding " << item->getIndefiniteArticle() << " " << yellow << item->getName() << white << " in your hand." << std::endl;
					else
						std::cout << "You're not holding anything in your hands." << std::endl;
				}
				return;
			}
		}
	}
	
	std::cout << "You're not sure what to look for..." << std::endl;
}

///////////////////////////////////////
// EXAMINE
///////////////////////////////////////
Examine::Examine() : Command("examine")
{
	add("exa");
}
void Examine::execute(const CharacterPtr &character, const RoomPtr &room, const std::vector<std::string> &args)
{
	//This is only for players
	if(character->hasPlayer() == false)
		return;

	if(args.empty())
	{
		room->examine();
		return;
	}
	else if(args.size() == 1)
	{
        for(unsigned int i = 0; i < room->getExits().size(); i++)
		{
			//If argument is an object name, then look at the object.
			if(room->getExits()[i]->is(args[0]) || room->getExits()[i]->getNameAlias() == args[0])
			{
				room->getExits()[i]->look();
				return;
			}
		}
		for(unsigned int i = 0; i < room->getCharacters().size(); i++)
		{
			//If argument is a character name, then look at the character.
			if(room->getCharacters()[i]->is(args[0]))
			{
				room->getCharacters()[i]->examine();
				return;
			}
		}
		for(unsigned int i = 0; i < room->getObjects().size(); i++)
		{
			//If argument is an object name, then look at the object.
			if(room->getObjects()[i]->is(args[0]))
			{
				room->getObjects()[i]->examine();
				return;
			}
		}
		for(unsigned int i = 0; i < character->getItems().size(); i++)
		{
			//If argument is an object name, then look at the object.
			if(character->getItems()[i]->is(args[0]))
			{
				character->getItems()[i]->examine();
				return;
			}
		}
	}

	std::cout << "You're not sure what to look for..." << std::endl;
}
